package com.itfreer.file.client;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.Map;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.stereotype.Component;

import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.AppendObjectRequest;
import com.aliyun.oss.model.AppendObjectResult;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.UploadFileRequest;
import com.itfreer.file.FileSegmentInfo;
import com.itfreer.file.service.IObjectUploadService;

/**
 * 定义文件上传接口
 */
@Component
public class OssObjectUpload implements IObjectUploadService, BeanFactoryAware {
	
	protected static BeanFactory beanFactory;

	@Override
	public void setBeanFactory(BeanFactory bf) throws BeansException {
		beanFactory = bf;
	}
	
	private AliyunOssPara aliyunOssPara;
	
	private AliyunOssPara getPara(){
		if(aliyunOssPara==null){
			aliyunOssPara = (AliyunOssPara) beanFactory.getBean("aliyunOssPara");
		}
		return aliyunOssPara;
	}
	
	private OSSClient getClient(){
		OSSClient ossClient = new OSSClient(getPara().getEndpoint(), getPara().getAccessKeyId(), getPara().getAccessKeySecret());
		return ossClient;
	}
	
	/**
	 * 创建文件夹
	 * 多级目录创建最后一级即可，比如dir1/dir2/dir3/，创建dir1/dir2/dir3/即可，dir1/、dir1/dir2/不需要创建
	 * @param bucketName	存储块名称
	 * @param objectName	文件夹名称
	 */
	public void createDir(String bucketName, String objectName){
		// 创建OSSClient实例
		OSSClient ossClient = getClient();
		if(!objectName.endsWith("/")){
			objectName += "/";
		}
		ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(new byte[0]));
		// 关闭client
		ossClient.shutdown();
	}
	
	/**
	 * 上传文件流
	 * @param bucketName 	存储块名称
	 * @param objectKey		对象存储key
	 * @param inputStream	对象流
	 * @param meta			对象元数据
	 */
	public void putObject(String bucketName, String objectKey, InputStream inputStream, Map<String, String> metaMap){
		// 创建OSSClient实例
		OSSClient ossClient = getClient();
		
		// 创建上传Object的Metadata
		ObjectMetadata meta = new ObjectMetadata();
		if(metaMap!=null){
			for(String key : metaMap.keySet()){
				// 设置自定义元信息name的值为my-data
				meta.addUserMetadata(key, metaMap.get(key));
			}
		}
		
		ossClient.putObject(bucketName, objectKey, inputStream, meta);
		// 关闭client
		ossClient.shutdown();
	}
	
	/**
	 * 追加文件流
	 * @param bucketName	存储块名称
	 * @param objectKey		对象存储key
	 * @param inputStream	对象流
	 * @param position		追加位置
	 * @param meta			对象元数据
	 */
	public Long appendObject(String bucketName, String objectKey, InputStream inputStream, long position, Map<String, String> metaMap){
		// 创建OSSClient实例
		OSSClient ossClient = getClient();
		AppendObjectRequest appendObjectRequest = new AppendObjectRequest(bucketName, objectKey, inputStream);
		
		// 创建上传Object的Metadata
		ObjectMetadata meta = new ObjectMetadata();
		if(metaMap!=null){
			for(String key : metaMap.keySet()){
				// 设置自定义元信息name的值为my-data
				meta.addUserMetadata(key, metaMap.get(key));
			}
		}
				
		// 第一次追加
		appendObjectRequest.setPosition(position);
		appendObjectRequest.setMetadata(meta);
		
		AppendObjectResult appendObjectResult = ossClient.appendObject(appendObjectRequest);
		Long po = appendObjectResult.getNextPosition();
		// 关闭client
		ossClient.shutdown();
		return po;
	}
	
	/**
	 * 断点续传上传
	 * @param bucketName	存储块名称
	 * @param objectKey		对象存储key
	 * @param localFile		本地文件
	 * @param partSize		分片大小 默认100K
	 * @param meta			对象元数据
	 */
	public void uploadFile(String bucketName, String objectKey, String localFile, Integer partSize, Map<String, String> metaMap){
		// 创建OSSClient实例
		OSSClient ossClient = getClient();
		// 设置断点续传请求
		UploadFileRequest uploadFileRequest = new UploadFileRequest(bucketName, objectKey);
		// 指定上传的本地文件
		uploadFileRequest.setUploadFile(localFile);
//		if(taskNum!=null){
//			// 指定上传并发线程数
//			uploadFileRequest.setTaskNum(taskNum);
//		}
		if(partSize!=null){
			// 指定上传的分片大小
			uploadFileRequest.setPartSize(partSize);
		}
		// 开启断点续传
		uploadFileRequest.setEnableCheckpoint(true);
		// 设置元数据
		// 创建上传Object的Metadata
		ObjectMetadata meta = new ObjectMetadata();
		if(metaMap!=null){
			for(String key : metaMap.keySet()){
				// 设置自定义元信息name的值为my-data
				meta.addUserMetadata(key, metaMap.get(key));
			}
		}
		uploadFileRequest.setObjectMetadata(meta);
		
		// 断点续传上传
		try {
			ossClient.uploadFile(uploadFileRequest);
		} catch (Throwable e) {
			e.printStackTrace();
		}
		// 关闭client
		ossClient.shutdown();
	}

	@Override
	public boolean putObject(String bucketName, String objectKey, byte[] content, Map<String, String> meta) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean uploadFile(String bucketName, String objectKey, FileSegmentInfo part, Map<String, String> meta) {
		// TODO Auto-generated method stub
		return false;
	}
}
